using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;

namespace CollegePhoneCrawler
{
    public partial class CrawlerForm : Form
    {
        private HashSet<string> phoneNumbers;
        private HashSet<string> urls;
        private HttpClient client;
        private Regex phoneRegex;

        public CrawlerForm()
        {
            InitializeComponent();
            phoneNumbers = new HashSet<string>();
            urls = new HashSet<string>();
            client = new HttpClient();
            phoneRegex = new Regex(@"\b\d{3}[-.\s]?\d{3}[-.\s]?\d{4}\b", RegexOptions.Compiled);
        }

        private async void btnSearch_Click(object sender, EventArgs e)
        {
            txtResults.Clear();
            phoneNumbers.Clear();
            urls.Clear();

            string keyword = txtKeyword.Text;
            if (string.IsNullOrWhiteSpace(keyword))
            {
                MessageBox.Show("请输入关键字", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                List<string> searchResultUrls = await SearchGoogle(keyword);
                await CrawlUrls(searchResultUrls);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            DisplayResults();
        }

        private async Task<List<string>> SearchGoogle(string keyword)
        {
            string searchUrl = $"https://www.google.com/search?q={Uri.EscapeDataString(keyword)}";
            HttpResponseMessage response = await client.GetAsync(searchUrl);
            response.EnsureSuccessStatusCode();

            string html = await response.Content.ReadAsStringAsync();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html);

            List<string> resultUrls = new List<string>();
            HtmlNodeCollection links = doc.DocumentNode.SelectNodes("//a[@href]");

            if (links != null)
            {
                foreach (HtmlNode link in links)
                {
                    HtmlAttribute att = link.GetAttributeValue("href", null);
                    if (att != null && att.Value.StartsWith("/url?q="))
                    {
                        string url = att.Value.Substring(7).Split('&')[0];
                        resultUrls.Add(url);
                    }
                }
            }

            return resultUrls;
        }

        private async Task CrawlUrls(List<string> urlsToCrawl)
        {
            List<Task> tasks = new List<Task>();

            foreach (string url in urlsToCrawl)
            {
                if (phoneNumbers.Count >= 100) break;

                tasks.Add(Task.Run(async () =>
                {
                    try
                    {
                        HttpResponseMessage response = await client.GetAsync(url);
                        response.EnsureSuccessStatusCode();

                        string html = await response.Content.ReadAsStringAsync();
                        HtmlDocument doc = new HtmlDocument();
                        doc.LoadHtml(html);

                        string phoneNumber = ExtractPhoneNumber(doc);
                        if (!string.IsNullOrWhiteSpace(phoneNumber))
                        {
                            lock (phoneNumbers)
                            {
                                if (phoneNumbers.Count < 100)
                                {
                                    phoneNumbers.Add(phoneNumber);
                                    urls.Add(url);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"无法爬取URL: {url}\n错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }));
            }

            await Task.WhenAll(tasks);
        }

        private string ExtractPhoneNumber(HtmlDocument doc)
        {
            HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//*");
            if (nodes != null)
            {
                foreach (HtmlNode node in nodes)
                {
                    if (node.InnerText != null)
                    {
                        Match match = phoneRegex.Match(node.InnerText);
                        if (match.Success)
                        {
                            return match.Value;
                        }
                    }
                }
            }
            return null;
        }

        private void DisplayResults()
        {
            txtResults.AppendText("已爬取的URL:\n");
            foreach (string url in urls)
            {
                txtResults.AppendText(url + "\n");
            }

            txtResults.AppendText("\n找到的电话号码:\n");
            foreach (string phoneNumber in phoneNumbers)
            {
                txtResults.AppendText(phoneNumber + "\n");
            }
        }
    }

    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CrawlerForm());
        }
    }
}
